﻿using System;
using System.Collections.Generic;
using System.Text;

namespace M5.GeminiHybird.Core.Tool
{
    /// <summary>
    /// 数据流读取器
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BufferReader<T>
    {
        #region 索引器
        public T this[int i]
        {
            //每次使用索引器按照下标读取后, 都将下次读取的下标重设成下一个
            get
            {

                NextReadIndex = i + 1;
                return _buffer[i];
            }
            set
            {
                _buffer[i] = value;
            }
        }
        #endregion

        public BufferReader(T[] buffer)
        {
            InitBuffer(buffer);
        }

        public BufferReader(T[] buffer, int startReadIndex)
        {
            InitBuffer(buffer);
            NextReadIndex = startReadIndex;
        }

        /// <summary>
        /// Buffer长度
        /// </summary>
        public int Length { get; private set; }

        /// <summary>
        /// 下一次读取的下标
        /// </summary>
        private int NextReadIndex = 0;

        /// <summary>
        /// 内部缓存
        /// </summary>
        private T[] _buffer;

        /// <summary>
        /// 初始化缓存
        /// </summary>
        /// <param name="buffer"></param>
        private void InitBuffer(T[] buffer)
        {
            _buffer = new T[buffer.Length];
            this.Length = _buffer.Length;
            Array.Copy(buffer, 0, _buffer, 0, buffer.Length);
        }

        /// <summary>
        /// 跳过
        /// </summary>
        /// <param name="count">需要跳过的个数</param>
        public void Skip(int count = 1)
        {
            if (count >= _buffer.Length || (NextReadIndex + count) > _buffer.Length)
                throw new IndexOutOfRangeException("索引超过最大长度");

            NextReadIndex += count;

        }

        /// <summary>
        /// 读取一个数据
        /// </summary>
        /// <param name="autoSkip">是否需要自动跳过</param>
        /// <returns></returns>
        public T Read(bool autoSkip = true)
        {

            T result = _buffer[NextReadIndex];
            if (autoSkip) Skip();
            return result;
        }

        /// <summary>
        /// 读取范围数据
        /// </summary>
        /// <param name="length">读取长度</param>
        /// <param name="autoSkip">是否需要自动跳过</param>
        /// <returns></returns>
        public T[] ReadRange(int length, bool autoSkip = true)
        {
            if (NextReadIndex + length > _buffer.Length)
            {
                return ReadToEnd();
            }
            //throw new IndexOutOfRangeException("索引超过最大长度");

            T[] readArray = new T[length];
            Array.Copy(_buffer, NextReadIndex, readArray, 0, length);

            if (autoSkip) Skip(length);

            return readArray;
        }

        /// <summary>
        /// 读取到某个位置
        /// </summary>
        /// <param name="endIndex">从当前读取到的下标到该下标的所有数据</param>
        /// <returns></returns>
        public T[] ReadTo(int endIndex)
        {
            if (endIndex > _buffer.Length)
                throw new IndexOutOfRangeException("索引超过最大长度");

            T[] readArray = new T[endIndex - NextReadIndex];
            Array.Copy(_buffer, NextReadIndex, readArray, 0, readArray.Length);

            Skip(endIndex - NextReadIndex);

            return readArray;
        }

        /// <summary>
        /// 读取到结尾
        /// </summary>
        /// <returns></returns>
        public T[] ReadToEnd()
        {
            T[] readArray = new T[_buffer.Length - NextReadIndex];
            Array.Copy(_buffer, NextReadIndex, readArray, 0, readArray.Length);

            NextReadIndex = _buffer.Length - 1;

            return readArray;
        }

        /// <summary>
        /// 是否还有下一个数据
        /// </summary>
        /// <returns></returns>
        public bool HasNext()
        {
            return NextReadIndex < _buffer.Length - 1;
        }

    }
}
